<?php

namespace System;

/**
 * Description of FrontController
 *
 * @author nofear
 */
class FrontController {

    private $controller;
    private $namespace;
    private $method;
    private $Router;
    private $params;
    public static $_instance;
    
    private function __construct() {
        
    }
    
    public function getRouter() {
        return $this->Router;
    }

    public function setRouter(\Shared\Routers\IRouter $Router) {
        $this->Router = $Router;
    }
    
    public function dispatch() {
        if ( !$this->Router ) {
            throw new \Exception('No valid router found!', 500);
        }
        
        $uri = $this->Router->getURI();
        $routes = \Shared\Application::getInstance()->getConfig()->routes;
        $route = null;
        
        // CHOISE PACKAGE/ROUTE (Admin/Open)
        if ( count($routes) ) {
            foreach ( $routes as $k => $v ) {
                if ( stripos($uri, $k) === 0 && ($uri == $k || stripos($uri, $k . '/') === 0) ) {
                    $route = $v;
                    $this->namespace = $v['namespace'];
                    $uri = substr($uri, strlen($k) + 1);
                    break;
                }
            }
        } else {
            throw new \Exception('Router error!', 500);
        }
        
        if ( !$this->namespace && isset($routes['*']['namespace']) ) {
            $route = $routes['*'];
            $this->namespace = $route['namespace'];
        } else if ( !$this->namespace && !isset($routes['*']['namespace']) ) {
            throw new \Exception('Router error!', 500);
        }
        
        $this->params = explode('/', $uri);
        if ( $this->params[0] ) {
            $this->controller = $this->params[0];
            
            if ( isset($this->params[1]) ) {
                $this->method = $this->params[1];
                unset($this->params[1]);
                $this->params = array_values($this->params);
            } else {
                $this->method = $this->getDefaultMethod();
            }
            
            unset($this->params[0]);
        } else {
            $this->controller = $this->getDefaultController();
            $this->method = $this->getDefaultMethod();
            $this->namespace = 'Open\Pages';
        }
        
        if ( is_array($route) && isset($route['controllers']) ) {
            if ( isset($route['controllers'][$this->controller]['methods'][$this->method]) ) {
                $this->method = $route['controllers'][$this->controller]['methods'][$this->method];
            }
            
            if ( isset($route['controllers'][$this->controller]['to']) ) {
                $this->controller = $route['controllers'][$this->controller]['to'];
            }
        }
        $class = $this->namespace . '\\' . ucfirst($this->controller);

        if ( class_exists($class) ) {
            if ( !method_exists($class, $this->method) ) {
//                throw new \Exception('Class: ' . $class . ' has no method: ' . $this->method, 500);
                $this->params = array_merge(array($this->method), $this->params);
                $this->method = $this->getDefaultMethod();
            }
            
            $Controller = new $class;
            $controllerParams = array();
            if ( isset($route['controllers'][$this->controller]['params']) ) {
                $controllerParams = $route['controllers'][$this->controller]['params'];
            }
            
            if ( count($controllerParams) && !count($this->params) ) {
                
            }
            
            $Request = \Shared\Application::getInstance()->getRequest();
            $Request->setParams($this->params, $controllerParams);
            $Controller->{$this->method}();
            echo $Controller->render();
        } else {
            \Shared\Application::getInstance()->createNotFound();
        }
    }
    
    
    private function getDefaultController() {
        $this->controller = \Shared\Application::getInstance()->getConfig()->app['defaultController'];
        
        if (!$this->controller) {
            $this->controller = 'Home';
        }
        
        return $this->controller;
    }
    
    private function getDefaultMethod() {
        $this->method = \Shared\Application::getInstance()->getConfig()->app['defaultMethod'];
        
        if (!$this->method) {
            $this->method = 'index';
        }
        
        return $this->method;
    }
    
    
    public function getController() {
        return $this->controller;
    }

    public function getMethod() {
        return $this->method;
    }

    public function getParams() {
        return $this->params;
    }
    
    /**
     * 
     * @return \Shared\FrontController
     */
    public static function getInstance() {
        if ( !self::$_instance ) {
            self::$_instance = new self;
        }
        
        return self::$_instance;
    }
}
